package com.caiden_micheal.dynamic.process.service.impl;

import com.alibaba.fastjson2.JSON;
import com.caiden_micheal.base.constant.LoggerHead;
import com.caiden_micheal.base.dto.PageDTO;
import com.caiden_micheal.base.utils.BaseContext;
import com.caiden_micheal.base.vo.PageVo;
import com.caiden_micheal.dynamic.form_workflow.mapper.FormWorkflowMapper;
import com.caiden_micheal.dynamic.process.domain.DynamicProcess;
import com.caiden_micheal.dynamic.process.dto.DProcessQueryConditionDTO;
import com.caiden_micheal.dynamic.process.dto.FileMapDTO;
import com.caiden_micheal.dynamic.process.dto.findExistenceByFormWorkflowIdDTO;
import com.caiden_micheal.dynamic.process.dto.inner.UploadFileDTO;
import com.caiden_micheal.dynamic.process.mapper.DProcessMapper;
import com.caiden_micheal.dynamic.process.vo.DProcessQueryConditionVO;
import com.caiden_micheal.dynamic.record.domain.DFileRecord;
import com.caiden_micheal.dynamic.record.mapper.DFileRecordMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.caiden_micheal.base.domain.AjxResult;
import com.caiden_micheal.dynamic.process.dto.DProcessAddDTO;
import com.caiden_micheal.dynamic.process.service.DProcessService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DProcessServiceImpl implements DProcessService {
    private static final Logger logger = LoggerFactory.getLogger(DProcessServiceImpl.class);

    @Autowired
    private DProcessMapper dProcessMapper;
    @Autowired
    private FormWorkflowMapper formWorkflowMapper;
    @Autowired
    private DFileRecordMapper dFileRecordMapper;

    @Transactional
    @Override
    public AjxResult addDProcess(DProcessAddDTO dProcessAddDTO) {
        if (dProcessAddDTO == null || dProcessAddDTO.getTitle() == null || dProcessAddDTO.getFormWorkflowId() == null || dProcessAddDTO.getFormData() == null) {
            return AjxResult.paramError("参数传递有误");
        }
        try {
            FileMapDTO fileMapDTO = JSON.parseObject(dProcessAddDTO.getFormData(), FileMapDTO.class);
            if (fileMapDTO != null && fileMapDTO.getFile() != null && fileMapDTO.getFile().size() != 0) {
                for (UploadFileDTO uploadFileDTO : fileMapDTO.getFile()) {
                    DFileRecord dFileRecord = dFileRecordMapper.findByFileName(uploadFileDTO.getName());
                    if (dFileRecord == null) {
                        return AjxResult.paramError(uploadFileDTO.getName() + " 该文件已失效，请重新上传");
                    }
                }
                dFileRecordMapper.edit(fileMapDTO.getFile());
            }
            // 存储
            DynamicProcess dynamicProcess = new DynamicProcess();
            dynamicProcess.setTitle(dProcessAddDTO.getTitle());
            dynamicProcess.setFormWorkflowId(dProcessAddDTO.getFormWorkflowId());
            dynamicProcess.setFormData(dProcessAddDTO.getFormData());
            // 计算处理人
            dynamicProcess.setProcessorUsername("欧尼酱");
            dynamicProcess.setCreatorUsername(String.valueOf(BaseContext.getInfo().get("username")));
            // 计算当前节点
            dynamicProcess.setNodeId("idj-237923-2387joi-koxsj");
            dProcessMapper.insertDProcess(dynamicProcess);
            return AjxResult.success("添加成功");
        } catch (Exception e) {
            logger.error(e.toString());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjxResult.unknownError("数据库操作异常");
        }
    }

    @Transactional
    @Override
    public PageDTO queryCondition(DProcessQueryConditionDTO dProcessQueryConditionDTO) {
        PageVo page = dProcessQueryConditionDTO.getPage();
        if (page == null) {
            logger.warn(LoggerHead.warnHead() + "dProcessQueryConditionDTO.page is Null!");
            return null;
        }
        page.setCurrentIndex((long) (page.getCurrentPage() - 1) * page.getPageSize());
        try {
            dProcessQueryConditionDTO.setCreatorUsername(String.valueOf(BaseContext.getInfo().get("username")));
            List<DynamicProcess> dynamicProcessList = dProcessMapper.findPageQueryByCondition(dProcessQueryConditionDTO);
            Map<Long, Map<String, String>> displayNameMap;
            if (dynamicProcessList == null || dynamicProcessList.size() == 0) {
                return null;
            } else {
                List<Long> formWorkflowIdList = dynamicProcessList.stream().map(DynamicProcess::getFormWorkflowId).collect(Collectors.toList());
                displayNameMap = formWorkflowMapper.findMapByIdList(formWorkflowIdList);
            }
            List<DProcessQueryConditionVO> dProcessQueryConditionVOList = new ArrayList<>();
            for (DynamicProcess dynamicProcess : dynamicProcessList) {
                DProcessQueryConditionVO dProcessQueryConditionVO = new DProcessQueryConditionVO();
                BeanUtils.copyProperties(dynamicProcess, dProcessQueryConditionVO);
                dProcessQueryConditionVO.setDisplayName(displayNameMap.get(dynamicProcess.getFormWorkflowId()) != null ? displayNameMap.get(dynamicProcess.getFormWorkflowId()).get("display_name") : null);
                dProcessQueryConditionVOList.add(dProcessQueryConditionVO);
            }
            page.setCount(dProcessMapper.findPageQueryByConditionCount(dProcessQueryConditionDTO));
            return new PageDTO(dProcessQueryConditionVOList, page);
        } catch (Exception e) {
            logger.error(e.toString());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return null;
        }
    }

    @Override
    public AjxResult findExistenceByFormWorkflowId(findExistenceByFormWorkflowIdDTO findExistenceByFormWorkflowIdDTO) {
        if (findExistenceByFormWorkflowIdDTO == null || findExistenceByFormWorkflowIdDTO.getFormWorkflowId() == null) {
            return AjxResult.paramError("参数传递有误");
        }
        List<DynamicProcess> dynamicProcessList = dProcessMapper.findByFormWorkflowId(findExistenceByFormWorkflowIdDTO.getFormWorkflowId());
        if (dynamicProcessList != null && dynamicProcessList.size() != 0) {
            return AjxResult.paramError("该逻辑流程模板被" + dynamicProcessList.size() + "个流程所引用，无法直接操作");
        }
        return AjxResult.success("未被引用可操作");
    }
}
